package com.bank.java;

import com.bank.java.agent.OrderServiceImplTransformer;
import com.bank.java.agent.UserTransformer;
import java.lang.instrument.Instrumentation;
import java.lang.instrument.UnmodifiableClassException;

/**
 * -javaagent:D:\workspace\java-study\java-agent-demo\target\java-agent-demo-1.0-SNAPSHOT-jar-with-dependencies.jar=Hello
 * -javaagent:D:\workspace\java-study\java-agent-demo\target\java-agent-demo-1.0-SNAPSHOT-jar-with-dependencies.jar=World
 */
public class AgentDemo {
    /**
     * 该方法在main方法之前运行，与main方法运行在同一个JVM中
     * @param agentArgs
     * @param inst
     */
    public static void premain(String agentArgs, Instrumentation inst) {
        System.out.println("=========premain start方法执行1========");
        System.out.println(agentArgs);
        // Instrumentation 是 instrument 包中定义的一个接口，是agent技术主要使用的API，使用它来改变和重新定义类的行为
        inst.addTransformer(new UserTransformer());
        System.out.println("premain end");
    }

    /**
     * 不存在 premain(String agentArgs, Instrumentation inst)
     * 则会执行 premain(String agentArgs)
     * @param agentArgs
     */
    public static void premain(String agentArgs) {
        System.out.println("=========premain方法执行2========");
        System.out.println(agentArgs);

    }

    public static void agentmain(String agentArgs, Instrumentation inst) throws UnmodifiableClassException {
        System.out.println("=====loadagents after main======== run.args:" + agentArgs);
        //配置类重新加载，必须设置true
        inst.addTransformer(new OrderServiceImplTransformer(),true);
        Class<?>[] clazzes = inst.getAllLoadedClasses();
        for (Class<?> cls: clazzes) {
            if (cls.getName().equals("com.bank.study.pojo.Product")) {
                System.out.println(cls.getName());
                System.out.println("Reloading: " + cls.getName());
                inst.retransformClasses(cls);
            }else if (cls.getName().equals("com.bank.study.service.impl.OrderServiceImpl")){
                System.out.println(cls.getName());
                System.out.println("Reloading: " + cls.getName());
                inst.retransformClasses(cls);
            }
        }
        System.out.println("agent run completely.");
    }

}
